package top.xia17.plugins.fast.user.service.impl;

import top.xia17.plugins.fast.common.database.jpa.extension.JpaTxServiceImpl;
import top.xia17.plugins.fast.common.exceptions.BadRequestException;
import top.xia17.plugins.fast.common.utils.TreeUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import top.xia17.plugins.fast.user.dao.entity.Dept;
import top.xia17.plugins.fast.user.dao.repository.DeptRepository;
import top.xia17.plugins.fast.user.dao.repository.UserRepository;
import top.xia17.plugins.fast.user.ds.UserDDS;
import top.xia17.plugins.fast.user.model.dto.DeptDto;
import top.xia17.plugins.fast.user.model.mapstruct.DeptMapstruct;
import top.xia17.plugins.fast.user.service.DeptService;

import java.util.List;
import java.util.stream.Collectors;


/**
 * 部门service
 * @author admin
 */
@Service
@RequiredArgsConstructor
@UserDDS
public class DeptServiceImpl extends JpaTxServiceImpl<Dept,Long, DeptRepository> implements DeptService {

    private final DeptMapstruct deptMapstruct;
    private final UserRepository userRepository;

    @Override
    public void createBefore(Dept entity) {
        // 父节点是否存在
        this.checkPid(entity);
        if (this.baseRepository.countAllByName(entity.getName()) > 0) {
            throw new BadRequestException("部门名已存在");
        }
        if (entity.getSort() == null || entity.getSort() < 0) {
            entity.setSort(10);
        }
        entity.setSubCount(0);
    }

    @Override
    public void createAfter(Dept entity) {
        // 是否有父节点
        Dept parent = this.getAttributeBean("parent");
        if (parent != null) {
            parent.setSubCount(parent.getSubCount() + 1);
            this.baseRepository.save(parent);
        }

    }

    /**
     * 检查pid填写是否符合规范
     *
     * @param dept /
     */
    private void checkPid(Dept dept) {
        // 父节点是否存在
        if (dept.getPid() == null) {
            dept.setPid(0L);
        }
        if (dept.getPid() < 0) {
            throw new BadRequestException("参数异常，pid小于0");
        }
        if (dept.getPid() > 0) {
            Dept parent = this.findByIdOrThrow(dept.getPid());
            this.setAttribute("parent", parent);
        }
    }

    @Override
    public void updateBefore(Dept entity, Dept resource) {
        // 部门名是否存在
        if (!entity.getName().equals(resource.getName()) && this.baseRepository.countAllByName(entity.getName()) > 0) {
            throw new BadRequestException("部门名已存在");
        }
        // 父节点
        if (!entity.getPid().equals(resource.getPid())) {
            // 不能是自己
            if (resource.getId().equals(resource.getPid())) {
                throw new BadRequestException("父节点不能是自己");
            }
            this.setAttribute("changePid", true);
            this.setAttribute("oldPid", entity.getPid());
            // 父节点是否存在
            this.checkPid(resource);
        }
    }

    @Override
    public void updateAfter(Dept entity) {
        Boolean changePid = this.getAttributeBean("changePid");
        if (changePid == null || !changePid) {
            return;
        }
        // 说明修改了父节点
        Long oldPid = this.getAttributeBean("oldPid");
        if (oldPid != 0) {
            Dept oldDept = this.findByIdOrThrow(oldPid);
            oldDept.setSubCount(oldDept.getSubCount() - 1);
            this.baseRepository.save(oldDept);
        }
        Dept parent = this.getAttributeBean("parent");
        if (parent != null) {
            parent.setSubCount(parent.getSubCount() + 1);
            this.baseRepository.save(parent);
        }
    }

    @Override
    public void updateProperty(Dept entity, Dept resource) {
        entity.setEnabled(resource.getEnabled())
                .setCode(resource.getCode())
                .setPid(resource.getPid())
                .setSubCount(resource.getSubCount())
                .setSort(resource.getSort())
                .setName(resource.getName());
    }

    @Override
    public void deleteBefore(Dept entity) {
        // 存在子节点不能删除
        if (entity.getSubCount() != 0) {
            throw new BadRequestException("请先删除子部门！");
        }
        // 有用户绑定该部门也不能删除
        if (userRepository.countAllByDept(entity) > 0) {
            throw new BadRequestException("请先将在部门的用户移出！");
        }
    }

    @Override
    public void deleteAfter(Dept entity) {
        if (entity.getPid() != 0) {
            // 父节点的子节点数量-1
            Dept parent = this.findByIdOrThrow(entity.getPid());
            parent.setSubCount(parent.getSubCount() - 1);
            this.baseRepository.save(parent);
        }
    }


    @Override
    public void deleteBefore(List<Dept> entities) {
        entities.forEach(this::deleteBefore);
    }

    @Override
    public void deleteAfter(List<Dept> entities) {
        entities.forEach(this::deleteAfter);
    }

    @Override
    public List<DeptDto> getDeptTree() {
        List<DeptDto> list = deptMapstruct.toDto(this.findAll(null));
        // 获取根节点
        List<DeptDto> roots = list.stream().filter(d -> d.getPid() == 0).collect(Collectors.toList());
        if (roots.isEmpty()) {
            return roots;
        }
        // 构建树
        TreeUtil.build(roots,
                root->list.stream().filter(d->d.getPid().equals(root)).collect(Collectors.toList()),
                DeptDto::getId,
                DeptDto::setChildren);
        return roots;
    }
}
